import random
import re
import redis
from django.contrib.auth import authenticate

from django.contrib.auth.hashers import make_password
from rest_framework.views import APIView
from rest_framework.response import Response

from myitils import sms_code
from myitils.common import make_token,check_token

from myitils.captcha.send_sms import send_message

from .serializer import *
from django.http import HttpResponse
from myitils.captcha.captcha import captcha
import uuid

r1 = redis.Redis(db=1)
image_redis = redis.Redis(db=2)
sms_redis = redis.Redis(db=3)


class RegisterView(APIView):
    '''
    用户注册
        需要接收用户名，密码，确认密码，手机号
    '''

    def post(self, request):
        '''
         {'username': ['刘禹辰'], 'password1': ['123'], 'password2': ['123'], 'phone': ['19801593977']}
        '''
        print(request.data)
        # 获取网页提交数据
        username = request.data.get('username')
        password1 = request.data.get('password1')
        password2 = request.data.get('password2')
        phone = request.data.get('phone')
        # 判断数据是否完整
        if not all([username, password1, password2, phone]):
            return Response({'msg': "数据不完整", 'code': 200})
        # 判断手机号是否符合规则
        phone_set = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$')
        if not re.match(phone_set, phone):
            return Response({'msg': '手机号不正确', 'code': 400})
        # 获取用户对象，用来判断用户是否已注册
        user_obj = User.objects.filter(username=username)
        if user_obj:
            return Response({'msg': '用户已存在', 'code': 400})
        # 未注册时，进行两次密码验证
        if password1 == password2:
            # 重构反序列化添加数据
            user_data = {'username': username, 'password': make_password(password1), 'phone': phone}
            # 反序列化添加
            user_ser = UserModelSer(data=user_data)
            # 校验数据
            if user_ser.is_valid():
                # 校验成功，保存数据
                user_ser.save()
                # 注册成功，把注册过的用户名添加到Redis中
                r1.hincrby('username', username)
                # 返回注册成功
                return Response({'msg': '注册成功', 'code': 200})
            # 校验失败，返回错误信息
            else:
                return Response({'error': user_ser.errors, 'code': 400})
        # 两次密码不一致，返回报错信息
        else:
            return Response({'msg': '两次密码不一致', 'code': 400})


class Check_usernameView(APIView):
    '''
    同名用户判断
    '''

    def get(self, request):
        username = request.query_params.get('username')
        redis_username = r1.hget('username', username)
        if redis_username:
            return Response({'msg': '用户已存在', 'code': 400})
        else:
            return Response({'msg': '用户未注册', 'code': 200})


class ImageCodeView(APIView):
    '''
    生成图形验证码
    '''

    def get(self, request):
        image_id = request.GET.get('image_id')
        code, img = captcha.generate_captcha()
        print(code)

        # 保存到redis中
        image_redis.set(image_id, code, ex=300)
        return HttpResponse(img, 'image/png')


class GenerateUUIDView(APIView):

    def get(self, request):
        return Response({'msg': 'ok', 'code': 200, 'image_id': str(uuid.uuid4())})


class VerifyCode(APIView):
    def get(self, request):
        '''
        验证码比对
        '''
        # 获取网页提交数据
        image_id = request.query_params.get('image_id')
        image_code = request.query_params.get('image_code')
        # 通过image_id获取图形验证码
        redis_image_code = image_redis.get(image_id).decode()
        print(image_code, redis_image_code)
        if image_code == redis_image_code.lower():
            return Response({'msg': '通过', 'code': 200})
        else:
            return Response({'msg': '失败', 'code': 400})


class LoginView(APIView):
    def post(self, request):
        # 接收前端提交数据
        username = request.data.get('username')
        password = request.data.get('password')
        # 使用authenticate进行用户验证,验证通过，返回用户对象，否则返回None
        user = authenticate(username=username, password=password)
        if user:
            token=make_token(user.id)
            return Response({'msg': '登录成功', 'code': 200,'token':token,'user_id':user.id})
        else:
            return Response({'msg': '登录失败', 'code': 400})

r14=redis.Redis(db=14)

class GenerateVerifyCode(APIView):
    '''
    生成手机号验证码
    '''

    def post(self, request):
        code_id = request.data.get('code_id')
        phone = request.data.get("phone")
        msg_code='%06d' % random.randint(0,1000000)
        res=send_message.delay(phone,msg_code)#0或者 ('11111')
        print(res)
        sms_redis.set(code_id,sms_code,ex=300)
        return Response({'msg': 'ok', 'code': 200})



class PhoneVerifyView(APIView):
    """
        手机验证码比对
    """
    def post(self, request):
        code_id = request.data.get('code_id')
        sms_code = request.data.get('sms_code')

        # 通过code_id来获取redis当中手机号验证码，用来进行比对
        redis_code = sms_redis.get(code_id).decode()

        # 判断sms_code 和 redis_code 是否一致
        if sms_code == redis_code:
            return Response({'msg': 'ok', 'code': 200})
        else:
            return Response({'msg': '失败', 'code': 400})

class OauthTokenView(APIView):
    '''
    通过前端提交的code 去新浪服务器换取access——token
    '''
    def post(self,request):
        code=request.data.get('code')
        pass
